<template>
  <div class="side-panel" @mousedown.stop>
    <div class="section">
      <span class="title">Variables</span>
      <span class="codicon codicon-plus" @mousedown="handleAddVariable"></span>
    </div>
    <template v-for="(variable, index) in variables">
      <div class="item" :key="`item${index}`" @mousedown="() => handleItemClick(index)">
        <div>
          <span
            class="codicon"
            :class="{ 'codicon-chevron-down': expands[index], 'codicon-chevron-right': !expands[index] }"
          >
          </span>
          <span draggable="true" @dragstart="(ev) => handleDragStart(ev, index)">{{ variable.title }}</span>
        </div>
        <div>
          <span class="codicon codicon-pencil" @mousedown="(ev) => handleTitleEdit(ev, index)"></span>
          <span class="codicon codicon-trash" @mousedown="(ev) => handleDeleteVariable(ev, index)"></span>
        </div>
      </div>
      <template v-if="expands[index]">
        <div class="item" :key="`type${index}`">
          <div>
            <span>Type:</span>
            <span class="icon" :style="pinStyle(variable.type)"></span>
            <span>{{ variable.type }}</span>
          </div>
          <span :key="index" class="codicon codicon-pencil" @mousedown="() => handleTypeEdit(index)"></span>
        </div>
        <div class="item" :key="`default${index}`" v-if="isSimpleType(variable)">
          <div>
            <span>Default:</span>
            <input
              v-if="isBool(variable.type)"
              type="checkbox"
              :checked="variable.default"
              @change="(ev) => handleChange(ev, index)"
            />
            <input
              v-else-if="isString(variable.type)"
              type="text"
              :value="variable.default"
              @input="(ev) => handleInput(ev, variable.type, index)"
            />
            <input
              v-else-if="isInt(variable.type)"
              type="number"
              step="1"
              :value="variable.default"
              @input="(ev) => handleInput(ev, variable.type, index)"
            />
            <input
              v-else-if="isUInt(variable.type)"
              type="number"
              step="1"
              min="0"
              :value="variable.default"
              @input="handleInput"
            />
            <input v-else-if="isFloat(variable.type)" type="number" :value="variable.default" @input="handleInput" />
          </div>
        </div>
      </template>
    </template>
  </div>
</template>

<script>
import { mapState, mapMutations } from 'vuex';
import * as chroma from 'chroma-js';
const prototype = require('../prototype');

export default {
  data() {
    return {
      expands: [],
    };
  },

  mounted() {
    this.expands = this.variables.map(() => false);
  },

  methods: {
    ...mapMutations([
      'addVariable',
      'deleteVariable',
      'editVariableType',
      'editVariableTitle',
      'changeVariableDefault',
    ]),

    isSimpleType(variable) {
      return prototype.SIMPLE_TYPES.includes(variable.type);
    },

    pinStyle(type) {
      const color = prototype.typeColor(type);
      const chartsColor = `var(--vscode-charts-${color}`;
      return {
        backgroundColor: chroma.valid(chartsColor) ? chartsColor : color,
      };
    },

    handleChange(ev, index) {
      this.changeVariableDefault({ index, value: ev.currentTarget.checked });
    },

    handleInput(ev, type, index) {
      if (type === 'string') {
        this.changeVariableDefault({ index, value: ev.currentTarget.value });
      } else if (type === 'float' || type === 'double') {
        this.changeVariableDefault({ index, value: parseFloat(ev.currentTarget.value) });
      } else {
        this.changeVariableDefault({ index, value: parseInt(ev.currentTarget.value) });
      }
    },

    handleAddVariable() {
      this.addVariable(this.variables.length);
    },

    handleDeleteVariable(ev, index) {
      this.deleteVariable(index);
    },

    handleItemClick(index) {
      this.$set(this.expands, index, !this.expands[index]);
    },

    handleDragStart(ev, index) {
      ev.dataTransfer.setData('text/plain', index.toString());
    },

    handleTitleEdit(ev, index) {
      this.editVariableTitle({ variable: this.variables[index], index });
    },

    handleTypeEdit(index) {
      this.editVariableType({ variable: this.variables[index], index });
    },

    isBool(type) {
      return type === 'bool';
    },

    isInt(type) {
      return type.startsWith('int');
    },

    isUInt(type) {
      return type.startsWith('uint');
    },

    isFloat(type) {
      return type === 'float' || this.type === 'double';
    },

    isString(type) {
      return type === 'string';
    },
  },

  computed: {
    ...mapState(['variables']),
  },
};
</script>

<style scoped>
.side-panel {
  background-color: var(--vscode-sideBar-background);
  border-left: 1px solid var(--vscode-sideBar-border);
  flex: 0 0 300px;
  align-items: stretch;
}

.side-panel .section {
  display: flex;
  justify-content: space-between;
  align-items: center;
  background-color: var(--vscode-sideBarSectionHeader-background);
  color: var(--vscode-sideBarSectionHeader-foreground);
  border-bottom: thin solid var(--vscode-sideBarSectionHeader-border);
}

.side-panel .section .title {
  user-select: none;
  padding: 10px;
  font-size: 1.1em;
  text-transform: uppercase;
}

.side-panel .section .codicon {
  cursor: pointer;
  margin-right: 10px;
}

.side-panel .item {
  user-select: none;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 5px 10px;
}

.side-panel .item:hover,
.side-panel .item:active {
  background-color: var(--vscode-list-hoverBackground);
  color: var(--vscode-list-hoverForeground);
}

.side-panel .item div {
  display: flex;
  align-items: center;
}

.side-panel .item .codicon {
  margin-right: 10px;
}

.side-panel .item .codicon-pencil,
.side-panel .item .codicon-trash {
  visibility: hidden;
}

.side-panel .item:hover .codicon-pencil,
.side-panel .item:active .codicon-pencil,
.side-panel .item:hover .codicon-trash,
.side-panel .item:active .codicon-trash {
  visibility: visible;
}

.side-panel .item .icon {
  margin-left: 10px;
  margin-right: 10px;
  width: 10px;
  height: 10px;
  border-radius: 100%;
  border: thin solid var(--vscode-charts-lines);
  background-color: white;
  cursor: pointer;
}

.side-panel .item input {
  margin-left: 10px;
  align-self: flex-start;
}
</style>
